﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Acoris.Markdown
{
    enum AMLNodeType
    {
        Root,
        Collection,
        Item,
        Text
    }

    /// <summary>
    /// 表示一个AML文档节点
    /// </summary>
    internal class AMLParseNode
    {
        private int                     m_offset;
        protected int                   m_length;
        private string                  m_document;
        private AMLNodeType             m_type;
        private AMLParseNode            m_parent;
        private AMLParseNodeCollection  m_children;
        private int                     m_nodeNameLength;
        private int                     m_nodeNameOffset;
        protected int                   m_textOffset;
        protected int                   m_textLength;
        private string                  m_content;

        /// <summary>
        /// 初始化Aml文档节点
        /// </summary>
        /// <param name="parent">该节点的父节点</param>
        /// <param name="type">该节点的类型</param>
        /// <param name="offset">该节点内容在文档中的位置</param>
        /// <param name="length">该节点内容的长度</param>
        /// <param name="document">该节点的文档内容</param>
        public AMLParseNode(
            AMLParseNode parent, 
            AMLNodeType type,
            int offset, 
            int length,
            string document, 
            int nodeNameOffset,
            int nodeNameLength,
            int textOffset,
            int textLength)
        {
            m_offset = offset;
            m_length = length;
            m_parent = parent;
            m_children = new AMLParseNodeCollection();
            m_type = type;
            m_document = document;
            m_nodeNameOffset = nodeNameOffset;
            m_nodeNameLength = nodeNameLength;
            m_textOffset = textOffset;
            m_textLength = textLength;
            VerifyAccess();
        }

        /// <summary>
        /// 验证当前文档的正确性
        /// </summary>
        /// <exception cref="NullReferenceException">文档内容为空</exception>
        /// <exception cref="IndexOutOfRangeException">索引超出范围</exception>
        protected void VerifyAccess()
        {
            if (m_document == null)
            {
                throw new NullReferenceException();
            }

            // 验证偏移的正确性
            if (m_offset < 0 ||
                m_offset >= m_document.Length)
            {
                throw new IndexOutOfRangeException();
            }


        }

        /// <summary>
        /// 返回当前节点的标签名
        /// </summary>
        public string TagName
        {
            get { return m_document.Substring(m_nodeNameOffset, m_nodeNameLength); }
        }

        /// <summary>
        /// 返回当前节点的原始AML文档内容
        /// </summary>
        public string InnerAML
        {
            get { return m_document.Substring(m_offset, m_length); }
        }

        /// <summary>
        /// 
        /// </summary>
        public string InnerText {
            get { return m_document.Substring(m_textOffset, m_textLength); }
        }

        /// <summary>
        /// 获取当前节点的内容
        /// </summary>
        public string Content {
            get { return m_content; }
            set { m_content = value; }
        }

        /// <summary>
        /// 获取该节点的第一个子节点
        /// </summary>
        public AMLParseNode FirstChild
        {
            get { return m_children.Count > 0 ? m_children[0] : null; } 
        }

        /// <summary>
        /// 返回当前节点的子节点集合
        /// </summary>
        public AMLParseNodeCollection Children
        {
            get { return m_children; }
        }

        /// <summary>
        /// 获取当前节点的类型
        /// </summary>
        public AMLNodeType Type
        {
            get { return m_type; }
        }

        /// <summary>
        /// 获取与当前实例等价的字符串形式
        /// </summary>
        /// <returns>返回与当前实例等价的字符串形式</returns>
        public override string ToString()
        {
            return $"{m_type.ToString()},{TagName}";
        }
    }
}
